From e6f711a94ac48dcc747b0a9c38d152b4a7963b0d Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 30 Oct 2016 06:11:38 +0100 Subject: [PATCH] inspector: Add more infrastructure This one introduces the Recording object which is essentially a single instance of something that happened. The RenderRecording is an instance of an actual rendering operation. --- gtk/gtkwidget.c | 4 ++ gtk/inspector/Makefile.inc | 4 ++ gtk/inspector/recorder.c | 67 +++++++++++++++++++- gtk/inspector/recorder.h | 10 ++- gtk/inspector/recorder.ui | 2 +- gtk/inspector/recording.c | 104 ++++++++++++++++++++++++++++++++ gtk/inspector/recording.h | 55 +++++++++++++++++ gtk/inspector/renderrecording.c | 68 +++++++++++++++++++++ gtk/inspector/renderrecording.h | 64 ++++++++++++++++++++ gtk/inspector/window.c | 32 ++++++++++ gtk/inspector/window.h | 5 ++ 11 files changed, 411 insertions(+), 4 deletions(-) create mode 100644 gtk/inspector/recording.c create mode 100644 gtk/inspector/recording.h create mode 100644 gtk/inspector/renderrecording.c create mode 100644 gtk/inspector/renderrecording.h diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index cdb69f49ff..f7879b688d 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -68,6 +68,8 @@ #include "gtkgestureprivate.h" #include "gtkwidgetpathprivate.h" +#include "inspector/window.h" + /* for the use of round() */ #include "fallback-c89.c" @@ -15748,6 +15750,8 @@ gtk_widget_render (GtkWidget *widget, if (root == NULL) return; + gtk_inspector_record_render (widget, window, region, root); + context = gdk_window_begin_draw_frame (window, region); gsk_renderer_render (renderer, root, context); diff --git a/gtk/inspector/Makefile.inc b/gtk/inspector/Makefile.inc index 61adc3822c..7d3ed8e72f 100644 --- a/gtk/inspector/Makefile.inc +++ b/gtk/inspector/Makefile.inc @@ -20,6 +20,8 @@ inspector_c_sources = \ inspector/prop-editor.c \ inspector/prop-list.c \ inspector/recorder.c \ + inspector/recording.c \ + inspector/renderrecording.c \ inspector/resource-list.c \ inspector/selector.c \ inspector/signals-list.c \ @@ -51,6 +53,8 @@ inspector_h_sources = \ inspector/prop-editor.h \ inspector/prop-list.h \ inspector/recorder.h \ + inspector/recording.h \ + inspector/renderrecording.h \ inspector/resource-list.h \ inspector/selector.h \ inspector/signals-list.h \ diff --git a/gtk/inspector/recorder.c b/gtk/inspector/recorder.c index c545552b63..691954fdb3 100644 --- a/gtk/inspector/recorder.c +++ b/gtk/inspector/recorder.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Red Hat, Inc. + * Copyright (c) 2016 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,21 +20,63 @@ #include "recorder.h" +#include +#include + +#include "recording.h" +#include "renderrecording.h" + struct _GtkInspectorRecorderPrivate { GListStore *recordings; + GtkWidget *recordings_list; }; G_DEFINE_TYPE_WITH_PRIVATE (GtkInspectorRecorder, gtk_inspector_recorder, GTK_TYPE_BIN) +static GtkWidget * +gtk_inspector_recorder_recordings_list_create_widget (gpointer item, + gpointer user_data) +{ + GtkInspectorRecording *recording = GTK_INSPECTOR_RECORDING (item); + GtkWidget *widget; + char *str; + + str = g_strdup_printf ("Cute drawing at time %lld", (long long) gtk_inspector_recording_get_timestamp (recording)); + widget = gtk_label_new (str); + g_free (str); + gtk_widget_show_all (widget); + + return widget; +} + +static void +gtk_inspector_recorder_constructed (GObject *object) +{ + GtkInspectorRecorder *recorder = GTK_INSPECTOR_RECORDER (object); + GtkInspectorRecorderPrivate *priv = gtk_inspector_recorder_get_instance_private (recorder); + + G_OBJECT_CLASS (gtk_inspector_recorder_parent_class)->constructed (object); + + gtk_list_box_bind_model (GTK_LIST_BOX (priv->recordings_list), + G_LIST_MODEL (priv->recordings), + gtk_inspector_recorder_recordings_list_create_widget, + NULL, + NULL); +} + static void gtk_inspector_recorder_class_init (GtkInspectorRecorderClass *klass) { GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructed = gtk_inspector_recorder_constructed; gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/libgtk/inspector/recorder.ui"); gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorRecorder, recordings); + gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorRecorder, recordings_list); } static void @@ -43,4 +85,27 @@ gtk_inspector_recorder_init (GtkInspectorRecorder *vis) gtk_widget_init_template (GTK_WIDGET (vis)); } +void +gtk_inspector_recorder_record_render (GtkInspectorRecorder *recorder, + GtkWidget *widget, + GdkWindow *window, + const cairo_region_t *region, + GskRenderNode *node) +{ + GtkInspectorRecorderPrivate *priv = gtk_inspector_recorder_get_instance_private (recorder); + GtkInspectorRecording *recording; + GdkFrameClock *frame_clock; + + frame_clock = gtk_widget_get_frame_clock (widget); + + recording = gtk_inspector_render_recording_new (gdk_frame_clock_get_frame_time (frame_clock), + &(GdkRectangle) { 0, 0, + gdk_window_get_width (window), + gdk_window_get_height (window) }, + region, + node); + g_list_store_append (priv->recordings, recording); + g_object_unref (recording); +} + // vim: set et sw=2 ts=2: diff --git a/gtk/inspector/recorder.h b/gtk/inspector/recorder.h index 7684a7c1a9..7f0980b844 100644 --- a/gtk/inspector/recorder.h +++ b/gtk/inspector/recorder.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Red Hat, Inc. + * Copyright (c) 2016 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -42,7 +42,13 @@ typedef struct _GtkInspectorRecorderClass G_BEGIN_DECLS -GType gtk_inspector_recorder_get_type (void); +GType gtk_inspector_recorder_get_type (void); + +void gtk_inspector_recorder_record_render (GtkInspectorRecorder *recorder, + GtkWidget *widget, + GdkWindow *window, + const cairo_region_t *region, + GskRenderNode *node); G_END_DECLS diff --git a/gtk/inspector/recorder.ui b/gtk/inspector/recorder.ui index ca23b23cfe..32952b7d06 100644 --- a/gtk/inspector/recorder.ui +++ b/gtk/inspector/recorder.ui @@ -12,7 +12,7 @@ True horizontal - + True single diff --git a/gtk/inspector/recording.c b/gtk/inspector/recording.c new file mode 100644 index 0000000000..b51e0aea45 --- /dev/null +++ b/gtk/inspector/recording.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2016 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include "config.h" +#include + +#include "recording.h" + +enum +{ + PROP_0, + PROP_TIMESTAMP, + LAST_PROP +}; + +static GParamSpec *props[LAST_PROP] = { NULL, }; + + +G_DEFINE_TYPE (GtkInspectorRecording, gtk_inspector_recording, G_TYPE_OBJECT) + +static void +gtk_inspector_recording_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec) +{ + GtkInspectorRecording *recording = GTK_INSPECTOR_RECORDING (object); + + switch (param_id) + { + case PROP_TIMESTAMP: + g_value_set_int64 (value, recording->timestamp); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void +gtk_inspector_recording_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec) +{ + GtkInspectorRecording *recording = GTK_INSPECTOR_RECORDING (object); + + switch (param_id) + { + case PROP_TIMESTAMP: + recording->timestamp = g_value_get_int64 (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void +gtk_inspector_recording_class_init (GtkInspectorRecordingClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = gtk_inspector_recording_get_property; + object_class->set_property = gtk_inspector_recording_set_property; + + props[PROP_TIMESTAMP] = + g_param_spec_int64 ("timestamp", + "Timestamp", + "Timestamp when this event was recorded", + G_MININT64, G_MAXINT64, 0, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT); + + g_object_class_install_properties (object_class, LAST_PROP, props); +} + +static void +gtk_inspector_recording_init (GtkInspectorRecording *vis) +{ +} + +gint64 +gtk_inspector_recording_get_timestamp (GtkInspectorRecording *recording) +{ + return recording->timestamp; +} + +// vim: set et sw=2 ts=2: diff --git a/gtk/inspector/recording.h b/gtk/inspector/recording.h new file mode 100644 index 0000000000..dddfdc43fa --- /dev/null +++ b/gtk/inspector/recording.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#ifndef _GTK_INSPECTOR_RECORDING_H_ +#define _GTK_INSPECTOR_RECORDING_H_ + +#include + +#define GTK_TYPE_INSPECTOR_RECORDING (gtk_inspector_recording_get_type()) +#define GTK_INSPECTOR_RECORDING(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_INSPECTOR_RECORDING, GtkInspectorRecording)) +#define GTK_INSPECTOR_RECORDING_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_INSPECTOR_RECORDING, GtkInspectorRecordingClass)) +#define GTK_INSPECTOR_IS_RECORDING(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_INSPECTOR_RECORDING)) +#define GTK_INSPECTOR_IS_RECORDING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_INSPECTOR_RECORDING)) +#define GTK_INSPECTOR_RECORDING_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_INSPECTOR_RECORDING, GtkInspectorRecordingClass)) + + +typedef struct _GtkInspectorRecordingPrivate GtkInspectorRecordingPrivate; + +typedef struct _GtkInspectorRecording +{ + GObject parent; + + gint64 timestamp; +} GtkInspectorRecording; + +typedef struct _GtkInspectorRecordingClass +{ + GObjectClass parent; +} GtkInspectorRecordingClass; + +G_BEGIN_DECLS + +GType gtk_inspector_recording_get_type (void); + +gint64 gtk_inspector_recording_get_timestamp (GtkInspectorRecording *recording); + +G_END_DECLS + +#endif // _GTK_INSPECTOR_RECORDING_H_ + +// vim: set et sw=2 ts=2: diff --git a/gtk/inspector/renderrecording.c b/gtk/inspector/renderrecording.c new file mode 100644 index 0000000000..5c52226580 --- /dev/null +++ b/gtk/inspector/renderrecording.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2016 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include "config.h" +#include + +#include "renderrecording.h" + +G_DEFINE_TYPE (GtkInspectorRenderRecording, gtk_inspector_render_recording, GTK_TYPE_INSPECTOR_RECORDING) + +static void +gtk_inspector_render_recording_finalize (GObject *object) +{ + GtkInspectorRenderRecording *recording = GTK_INSPECTOR_RENDER_RECORDING (object); + + g_clear_pointer (&recording->clip, cairo_region_destroy); + g_clear_pointer (&recording->node, gsk_render_node_unref); + + G_OBJECT_CLASS (gtk_inspector_render_recording_parent_class)->finalize (object); +} + +static void +gtk_inspector_render_recording_class_init (GtkInspectorRenderRecordingClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gtk_inspector_render_recording_finalize; +} + +static void +gtk_inspector_render_recording_init (GtkInspectorRenderRecording *vis) +{ +} + +GtkInspectorRecording * +gtk_inspector_render_recording_new (gint64 timestamp, + const GdkRectangle *area, + const cairo_region_t *clip, + GskRenderNode *node) +{ + GtkInspectorRenderRecording *recording; + + recording = g_object_new (GTK_TYPE_INSPECTOR_RENDER_RECORDING, + "timestamp", timestamp, + NULL); + + recording->area = *area; + recording->clip = cairo_region_copy (clip); + recording->node = gsk_render_node_ref (node); + + return GTK_INSPECTOR_RECORDING (recording); +} + +// vim: set et sw=2 ts=2: diff --git a/gtk/inspector/renderrecording.h b/gtk/inspector/renderrecording.h new file mode 100644 index 0000000000..ce0a99340a --- /dev/null +++ b/gtk/inspector/renderrecording.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2016 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#ifndef _GTK_INSPECTOR_RENDER_RECORDING_H_ +#define _GTK_INSPECTOR_RENDER_RECORDING_H_ + +#include +#include + +#include "inspector/recording.h" + +G_BEGIN_DECLS + +#define GTK_TYPE_INSPECTOR_RENDER_RECORDING (gtk_inspector_render_recording_get_type()) +#define GTK_INSPECTOR_RENDER_RECORDING(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_INSPECTOR_RENDER_RECORDING, GtkInspectorRenderRecording)) +#define GTK_INSPECTOR_RENDER_RECORDING_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_INSPECTOR_RENDER_RECORDING, GtkInspectorRenderRecordingClass)) +#define GTK_INSPECTOR_IS_RENDER_RECORDING(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_INSPECTOR_RENDER_RECORDING)) +#define GTK_INSPECTOR_IS_RENDER_RECORDING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GTK_TYPE_INSPECTOR_RENDER_RECORDING)) +#define GTK_INSPECTOR_RENDER_RECORDING_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_INSPECTOR_RENDER_RECORDING, GtkInspectorRenderRecordingClass)) + + +typedef struct _GtkInspectorRenderRecordingPrivate GtkInspectorRenderRecordingPrivate; + +typedef struct _GtkInspectorRenderRecording +{ + GtkInspectorRecording parent; + + GdkRectangle area; + cairo_region_t *clip; + GskRenderNode *node; +} GtkInspectorRenderRecording; + +typedef struct _GtkInspectorRenderRecordingClass +{ + GtkInspectorRecordingClass parent; +} GtkInspectorRenderRecordingClass; + +GType gtk_inspector_render_recording_get_type (void); + +GtkInspectorRecording * + gtk_inspector_render_recording_new (gint64 timestamp, + const GdkRectangle *area, + const cairo_region_t *clip, + GskRenderNode *node); + +G_END_DECLS + +#endif // _GTK_INSPECTOR_RENDER_RECORDING_H_ + +// vim: set et sw=2 ts=2: diff --git a/gtk/inspector/window.c b/gtk/inspector/window.c index 9f84a5c52f..beb0db9d31 100644 --- a/gtk/inspector/window.c +++ b/gtk/inspector/window.c @@ -42,6 +42,7 @@ #include "misc-info.h" #include "gestures.h" #include "magnifier.h" +#include "recorder.h" #include "gtklabel.h" #include "gtkbutton.h" @@ -228,6 +229,8 @@ gtk_inspector_window_constructed (GObject *object) G_OBJECT_CLASS (gtk_inspector_window_parent_class)->constructed (object); + g_object_set_data (G_OBJECT (gdk_display_get_default ()), "-gtk-inspector", iw); + gtk_inspector_object_tree_scan (GTK_INSPECTOR_OBJECT_TREE (iw->object_tree), NULL); } @@ -332,4 +335,33 @@ gtk_inspector_window_rescan (GtkWidget *widget) gtk_inspector_object_tree_scan (GTK_INSPECTOR_OBJECT_TREE (iw->object_tree), NULL); } +static GtkInspectorWindow * +gtk_inspector_window_get_for_display (GdkDisplay *display) +{ + return g_object_get_data (G_OBJECT (display), "-gtk-inspector"); +} + +void +gtk_inspector_record_render (GtkWidget *widget, + GdkWindow *window, + const cairo_region_t *region, + GskRenderNode *node) +{ + GtkInspectorWindow *iw; + + iw = gtk_inspector_window_get_for_display (gtk_widget_get_display (widget)); + if (iw == NULL) + return; + + /* sanity check for single-display GDK backends */ + if (GTK_WIDGET (iw) == widget) + return; + + gtk_inspector_recorder_record_render (GTK_INSPECTOR_RECORDER (iw->widget_recorder), + widget, + window, + region, + node); +} + // vim: set et sw=2 ts=2: diff --git a/gtk/inspector/window.h b/gtk/inspector/window.h index 13d066a4e6..0ca153d2cc 100644 --- a/gtk/inspector/window.h +++ b/gtk/inspector/window.h @@ -106,6 +106,11 @@ void gtk_inspector_window_select_widget_under_pointer (GtkInspectorWindow void gtk_inspector_window_rescan (GtkWidget *iw); +void gtk_inspector_record_render (GtkWidget *widget, + GdkWindow *window, + const cairo_region_t *region, + GskRenderNode *node); + G_END_DECLS -- 2.30.2